import {ArgumentMetadata, HttpStatus, Injectable, PipeTransform} from "@nestjs/common";
import {plainToClassFromExist} from "class-transformer";
import {validate} from "class-validator";
import {MyHttpException} from "../exception/MyHttpException";
import {MyHttpStatusEnum} from "../enum/MyHttpStatusEnum";
import {Validate_Mods} from "../enum/ValidateModsEnum";

/**
 * Dto校验管道
 */
@Injectable()
export class MyValidationPipe implements PipeTransform {
    // 校验模式
    private readonly validateMods: [Validate_Mods];

    constructor(mods?:[Validate_Mods]) {
        this.validateMods = mods;
    }

    async transform(value: any, { metatype }: ArgumentMetadata) {
        console.log('MyValidatePipe is invoked....')
        // 如果没有校验逻辑则直接返回dto的值
        if (!metatype || !MyValidationPipe.toValidate(metatype)) {
            return value;
        }
        let object = plainToClassFromExist(metatype, value);
        const errors = await validate(object, {groups: this.validateMods});
        if (errors.length > 0) {
            // 取自定义的错误信息
            const errorMsg = Object.values(errors[0].constraints)[0];
            throw new MyHttpException(errorMsg, MyHttpStatusEnum.BAD_REQUEST, HttpStatus.BAD_REQUEST);
        }
        return value;
    }

    private static toValidate(metatype: Function): boolean {
        const types: Function[] = [String, Boolean, Number, Array, Object];
        return !types.includes(metatype);
    }

}
